#include "../include/analysisCommand.h"

int dir_is_legal(char path[]){               

    if(access(path, F_OK) == 0){
        return 1;
    }
    else{
        return 0;
    }
}
int is_dir(char path[]){
    if(access(path, F_OK) == 0){
        struct stat sb;
        if(stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)){
            return 1;
        }
    }
    return 0;
}
int do_command(Command curCommand, int sockfd, commandStack_t *pcommandStack, commandStack_t *curPathStack){
    switch (curCommand){
    case DATA:{

                  break;
              }
    case CD:{
                // 使用当前工作目录curPathStack
                do_cd(sockfd,pcommandStack,curPathStack);
                printf("do cd.\n");
                break;
            }
    case LS:{
                do_ls(sockfd, pcommandStack, curPathStack);
                printf("do ls.\n");
                break;
            }
    case PUTS:{
                  char buf[1024]={0};
                  assemble_stack(pcommandStack, buf);
                  printf("do command: buf = %s\n",buf);
                  do_puts(sockfd,pcommandStack);
                  printf("do puts.\n");
                  break;
              }
    case GETS:{
                  do_gets(sockfd,pcommandStack);
                  printf("do gets.\n");
                  break;
              }
    case REMOVE:{
                    do_rmdir(sockfd,pcommandStack);
                    printf("do remove.\n");
                    break;
                }
    case PWD:{
                 // 只使用当前工作目录curPathStack
                 do_pwd(sockfd,curPathStack);
                 printf("do pwd.\n");
                 break;
             }
    case MKDIR:{
                   do_mkdir(sockfd,pcommandStack);
                   printf("do mkdir.\n");
                   break;
               }
    }    
    return 0;
}
// 测试打印函数
void test_print(commandStack_t *pcommandStack){
    stackNode_t *curNode = pcommandStack->pBottom;
    while(curNode){
        printf("%s", curNode->data);
        curNode = curNode->next;
    }
    printf("\n");
}


// 一次性接收
int recvnCommand(int sockfd, void *buf, int length){
    ssize_t cur_len = 0;
    char *p = (char *)buf;
    while(cur_len < length){
        ssize_t sret = recv(sockfd, p+cur_len, length-cur_len, 0);
        cur_len += sret;
    }
    return 0;
}

int handle_mkdir(int sockfd, commandStack_t *curPathStack, commandStack_t *pcommandStack){
    comTrain_t train;
    int nodeCount = 0;
    char pathBuf[1024] = {0};
    while(1){
        bzero(train.data, sizeof(train.data));
        recvnCommand(sockfd, &train.type, sizeof(train.type));
        recvnCommand(sockfd, &train.length, sizeof(train.length));
        if(train.type == DATA && train.length == 0){
            break;
        }
        recvnCommand(sockfd, train.data, train.length);
        if(pcommandStack->stackSize == 0){
            char *ch = train.data;
            if(*ch == '/'){  // 判断根目录下是否有该目录
                // 先把/home/user/zhangsan无脑压入栈中
                get_homedir(pathBuf);
                push_command_stack(pcommandStack, pathBuf, strlen(pathBuf));
                // 把该结点压入栈中
                push_command_stack(pcommandStack, train.data, train.length);
            }else{
                // 把当前工作目录压入栈中
                assemble_stack(curPathStack, pathBuf);
                push_command_stack(pcommandStack, pathBuf, strlen(pathBuf));
                // 把该结点压入栈中
                char tmp[1024] = {0};
                tmp[0] = '/';
                strcat(tmp, train.data);
                train.length++;
                push_command_stack(pcommandStack, tmp, train.length);
            }
            nodeCount += 2;
            continue;
        }
        // 先全部无脑压入栈中
        push_command_stack(pcommandStack, train.data, train.length);
        nodeCount++;
    }
    printf("mkdir print:");                          
    test_print(pcommandStack);
    printf("cur print:");
    test_print(curPathStack);
    stackNode_t *checkNode = pcommandStack->pBottom;
    bzero(pathBuf, sizeof(pathBuf));
    // 只检查除最后一个路径子项外的其他路径是否合法
    for(int i = 0; i < nodeCount-1; i++){
        strcat(pathBuf, checkNode->data);
        checkNode = checkNode->next;
    }
    printf("pathBuf = %s\n", pathBuf);
    if(is_dir(pathBuf)){
        return 1;
    }else{
        trans_res(sockfd, "新建目录失败！请检查路径");
        clear_stack(pcommandStack);
    }
    return 0;
}
int recv_blank(int sockfd){
    int type = 0;
    recv(sockfd,&type,sizeof(type),0);
    int length = 0;
    recv(sockfd,&length,sizeof(length),0);
    return 0;
}
int recvCommand(int sockfd, commandStack_t *curPathStack){
    comTrain_t train;
    // 接收命令
    recvnCommand(sockfd, &train.type, sizeof(Command));
    Command curCommand = train.type; 
    printf("train.type = %d\n", train.type);
    if(curCommand < DATA || curCommand > MKDIR){
        trans_res(sockfd, "命令无效！请重新输入\n");
        printf("命令无效！\n");
        return 0;
    }

    // 将路径存在栈里
    commandStack_t pcommandStack;
    init_command_stack(&pcommandStack);
    if(curCommand == MKDIR){
        if(handle_mkdir(sockfd, curPathStack, &pcommandStack)){
            do_command(curCommand, sockfd, &pcommandStack, curPathStack);
            printf("执行完命令后，当前工作目录为：");
            test_print(curPathStack);

        }
        return 0;
    }
    if(curCommand == PWD){
        while(1){
            recvnCommand(sockfd, &train.type, sizeof(train.type));
            recvnCommand(sockfd, &train.length, sizeof(train.length));
            if(train.type == DATA && train.length == 0){ 
                break;
            }   
            recvnCommand(sockfd, &train.data, train.length);
            push_command_stack(&pcommandStack, train.data, train.length);
        }
        do_command(curCommand, sockfd, &pcommandStack, curPathStack);
        printf("执行完命令后，当前工作目录为：");
        test_print(curPathStack);
        clear_stack(&pcommandStack);
        return 0;
    }
    if(curCommand == PUTS)
    {
       do_puts(sockfd,curPathStack); 
    }
    while(1){
        bzero(train.data, sizeof(train.data));
        recvnCommand(sockfd, &train.type, sizeof(train.type));
        recvnCommand(sockfd, &train.length, sizeof(train.length));
        if(train.type == DATA && train.length == 0){
            break;
        }
        recvnCommand(sockfd, &train.data, train.length);
        printf("train.data = %s\n",train.data);
        char pathBuf[1024] = {0};
        // 对路径的起始单个目录进行特殊处理（在当前目录合法or在根目录合法）
        if(pcommandStack.stackSize == 0){
            char *ch = train.data;
            if(*ch == '/'){ // 判断根目录下有无此目录
                get_homedir(pathBuf);
                push_command_stack(&pcommandStack, pathBuf, strlen(pathBuf));
                strcat(pathBuf, train.data);
                if(dir_is_legal(pathBuf)){
                    push_command_stack(&pcommandStack, train.data, train.length);
                }else{
                    trans_res(sockfd, "查无此路径！");
                    clear_stack(&pcommandStack);
                    recv_blank(sockfd);
                    return 0;
                }
            }
            else{ // 判断当前工作目录下有无此目录
                  // 将当前工作目录压入命令栈中
                stackNode_t *pCur = curPathStack->pBottom;
                while(pCur){
                    push_command_stack(&pcommandStack, pCur->data, strlen(pCur->data));
                    pCur = pCur->next;
                }
                assemble_stack(curPathStack, pathBuf);
                strcat(pathBuf, "/");
                strcat(pathBuf, train.data);
                /* printf("pathBuf = %s\n", pathBuf); */
                if(dir_is_legal(pathBuf)){
                    char tmp[1024] = {0};
                    tmp[0] = '/';
                    strcat(tmp, train.data);
                    train.length++;
                    push_command_stack(&pcommandStack, tmp, train.length);
                }else{
                    trans_res(sockfd, "查无此路径！");
                    clear_stack(&pcommandStack);
                    recv_blank(sockfd);
                    return 0;
                }

            }
            continue;
        }
        if(strcmp(train.data, "/")==0){
            continue;
        }
        bzero(pathBuf, sizeof(pathBuf));
        stackNode_t *pCur = pcommandStack.pBottom;
        while(pCur){
            strcat(pathBuf, pCur->data);
            pCur = pCur->next;
        }
        strcat(pathBuf, train.data);
        if(dir_is_legal(pathBuf)){
            push_command_stack(&pcommandStack, train.data, train.length);
        }else{
            trans_res(sockfd, "查无此路径！");
            clear_stack(&pcommandStack);
            recv_blank(sockfd);
            return 0;
        }
        printf("test print:");
        test_print(&pcommandStack);
        printf("cur print:");
        test_print(curPathStack);
    }
    do_command(curCommand, sockfd, &pcommandStack, curPathStack);
    printf("执行完命令后，当前工作目录为：");
    test_print(curPathStack);
    return 0;
}
